import Vue from "vue";
const apiForm = window.$api.custmerForm.scheme;

export default function () {
  return {
    data() {
      return {
        formSchemeLoding: false,

        currentNode: {},
        processId: "",

        formAuthFieldsMap: {},
        formRequiredMap: {},

        isUpdate: false,
        showForm: false,

        formType: "1", // 1.自定义表单 2.系统表单
        formRelationId: "", // 表单关联字段
        formRelationKey: "", // 具体关联的表字段名
        formSchemeId: "",
        formInfo: null,
        sysFormComponent: "",

        hasWfForm: false,

        formScheme: null,
      };
    },
    methods: {
      async loadForm(currentNode, processId, params, isLoadFormData, readonly) {
        // 加载表单信息
        if (!currentNode) {
          return;
        }
        this.showForm = false;
        this.formSchemeLoding = true;

        this.currentNode = currentNode;
        const { formType, formVerison, formRelationId, formUrl, authFields } = currentNode;

        this.formRelationId = formRelationId;
        this.formType = formType;

        this.processId = processId;
        this.params = params;

        this.hasWfForm = true;

        if (formType == "1") {
          // 自定义表单
          const { f_Scheme } = await this.$awaitWraper(apiForm.getHistory(formVerison));
          const formScheme = JSON.parse(f_Scheme);
          this.formScheme = formScheme;

          this.formSchemeId = formVerison;

          const formAuthFieldsMap = {};
          authFields.forEach((item) => {
            if (readonly) item.isEdit = false;
            formAuthFieldsMap[item.prop] = item;
          });

          const formInfo = formScheme.formInfo;
          formInfo.tabList.forEach((tab) => {
            tab.components.forEach((component) => {
              if (!["gridtable"].includes(component.type)) {
                if (component.display) {
                  if (formAuthFieldsMap[component.prop]) {
                    component.required = formAuthFieldsMap[component.prop].required;
                  }
                }
              } else {
                component.children.forEach((cell) => {
                  if (formAuthFieldsMap[cell.prop]) {
                    cell.required = formAuthFieldsMap[cell.prop].required;
                  }
                });
              }

              if (component.prop == this.formRelationId) {
                this.formRelationKey = component.field;
              }
            });
          });

          this.formAuthFieldsMap = formAuthFieldsMap;

          this.formInfo = formInfo;
        } else {
          // 系统表单
          const WFFormComponent = Vue.component(formUrl);
          if (WFFormComponent == undefined) {
            this.hasWfForm = false;
            this.$message({
              type: "warning",
              message: "无法加载系统表单，请查看流程配置是否正确!",
            });
          } else {
            this.sysFormComponent = formUrl;

            const formAuthFieldsMap = {};
            authFields.forEach((item) => {
              const propList = item.field.split("|");
              let code = "3";
              if (item.isLook || item.isEdit) {
                code = item.isEdit ? "2" : "1";
              }

              if (propList.length > 1) {
                // 表格
                formAuthFieldsMap[propList[0].toLowerCase()] = formAuthFieldsMap[propList[0].toLowerCase()] || {};
                formAuthFieldsMap[propList[0].toLowerCase()][propList[1].toLowerCase()] = code;

                if (item.isEdit) {
                  this.formRequiredMap[propList[0].toLowerCase()] =
                    this.formRequiredMap[propList[0].toLowerCase()] || {};
                  this.formRequiredMap[propList[0].toLowerCase()][propList[1].toLowerCase()] = item.required;
                }
              } else {
                // 表单字段
                formAuthFieldsMap[propList[0].toLowerCase()] = code;
                if (item.isEdit) {
                  this.formRequiredMap[propList[0].toLowerCase()] = item.required;
                }
              }
            });

            this.formAuthFieldsMap = formAuthFieldsMap;
          }
        }

        this.showForm = true;

        // 加载表单数据
        if (isLoadFormData && this.hasWfForm) {
          if (formType == "1") {
            if (this.formScheme.formType == 2) {
              const apiGet = this.formScheme.db.find((item) => item.apiType == 1);
              const api = await this.$awaitWraper(apiForm.apiParams(`${this.apiUrl}data/datainterface/${apiGet.f_Id}`));
              const res = await this.$awaitWraper(
                apiForm.request(`${api.f_Url}/${this.processId}`, api.f_RequestMethod)
              );
              if (res) {
                this.isUpdate = true;
                this.$nextTick(() => {
                  this.$refs.wfForm.init(this.turnApiDataForm(res));
                });
              } else {
                this.isUpdate = false;
                this.$nextTick(() => {
                  this.$refs.wfForm.init();
                });
              }
            } else {
              const data = await this.$awaitWraper(
                apiForm.getData(this.formSchemeId, { key: this.formRelationKey, keyValue: this.processId })
              );
              if (data) {
                this.isUpdate = true;
                this.$nextTick(() => {
                  this.$refs.wfForm.init(data);
                });
              } else {
                this.isUpdate = false;
                this.$nextTick(() => {
                  this.$refs.wfForm.init();
                });
              }
            }

            this.formSchemeLoding = false;
          } else {
            this.loadSystemFormData();
          }
        } else {
          this.isUpdate = false;
          this.$nextTick(() => {
            this.$refs.wfForm.init();
          });
          this.formSchemeLoding = false;
        }
      },

      loadSystemFormData() {
        // 加载系统表单数据
        if (this.$refs.wfForm) {
          this.$nextTick(async () => {
            this.isUpdate = await this.$refs.wfForm.loadFormData({
              keyValue: this.processId,
              params: this.params,
              node: this.currentNode,
            });
            this.formSchemeLoding = false;
          });
        } else {
          setTimeout(async () => {
            this.loadSystemFormData();
          }, 100);
        }
      },

      resetWfForm() {
        this.isUpdate = false;
        this.showForm = false;
        this.hasWfForm = false;
      },

      validateWfForm() {
        if (!this.hasWfForm) {
          return true;
        }
        return this.$refs.wfForm.validateForm();
      },

      getWfForm() {
        // 获取表单信息
        const formData = this.$refs.wfForm.getForm();
        if (this.$validatenull(this.formRelationId)) {
          this.$message({
            type: "error",
            message: this.$t("请设置表单和流程关联字段!"),
          });
          return null;
        }
        formData[this.formRelationId] = this.processId;

        const postData = {
          schemeId: this.formSchemeId,
          isUpdate: this.isUpdate,
          pkey: this.formRelationId,
          pkeyValue: this.processId,
          data: JSON.stringify(formData),
        };
        return postData;
      },

      // 保存表单数据
      async saveWfForm(code) {
        if (!this.hasWfForm) {
          return true;
        }

        if (this.formType == "1") {
          if (this.formScheme.formType == 2) {
            const formData = this.$refs.wfForm.getForm();
            const apiPost = this.formScheme.db.find((item) => item.f_RequestMethod == "post");
            const apiPut = this.formScheme.db.find((item) => item.f_RequestMethod == "put");
            const apiSave = this.$deepClone(this.formScheme.output.apiSave);

            let api;
            if (this.isUpdate) {
              let params = this.turnSavetoFormData(formData, apiSave);
              api = await this.$awaitWraper(apiForm.apiParams(`${this.apiUrl}data/datainterface/${apiPut.f_Id}`));
              await this.$awaitWraper(apiForm.apiData(`${api.f_Url}/${this.processId}`, api.f_RequestMethod, params));
            } else {
              api = await this.$awaitWraper(apiForm.apiParams(`${this.apiUrl}data/datainterface/${apiPost.f_Id}`));
              formData[this.formRelationId] = this.processId;
              let params = this.turnSavetoFormData(formData, apiSave);
              await this.$awaitWraper(apiForm.apiData(`${api.f_Url}`, api.f_RequestMethod, params));
            }
          } else {
            // 自定义表单

            const data = this.getWfForm();
            if (data != null) {
              await apiForm.saveData(data);
              this.isUpdate = true;
            } else {
              return false;
            }
          }
        } else {
          return this.$refs.wfForm.saveForm({
            keyValue: this.processId,
            isEdit: this.isUpdate,
            code,
            node: this.currentNode,
          });
        }

        return true;
      },
      turnApiDataForm(data) {
        let formdata = {};
        if (Object.prototype.toString.call(data) == "[object Object]") {
          const mainTable = Object.keys(data).filter((key) => {
            return !(Object.prototype.toString.call(data[key]) == "[object Object]" || Array.isArray(data[key]));
          });

          if (mainTable.length) {
            const mainData = mainTable.reduce((acc, crr) => {
              acc[crr.toLowerCase()] = data[crr];
              return acc;
            }, {});
            formdata = {
              root: [mainData],
            };
          }

          const childTable = Object.keys(data).filter((key) => {
            return Object.prototype.toString.call(data[key]) == "[object Object]" || Array.isArray(data[key]);
          });

          childTable.forEach((key) => {
            formdata[key.toLowerCase()] = [this.turnToLowerCase(data[key])];
          });
        }
        return formdata;
      },
      turnToLowerCase(data) {
        let formData;
        if (Object.prototype.toString.call(data) == "[object Object]") {
          formData = {};
          Object.keys(data).forEach((key) => {
            formData[key.toLowerCase()] = data[key];
          });
        } else if (Array.isArray(data)) {
          formData = data.map((item) => {
            if (Object.prototype.toString.call(item) == "[object Object]") {
              let temp = {};
              Object.keys(item).forEach((key) => {
                temp[key.toLowerCase()] = item[key];
              });
              return temp;
            }
            return item;
          });
        } else {
          formData = data;
        }
        return formData;
      },
      turnSavetoFormData(formData, apiSave) {
        const feildMaps = apiSave.reduce((arr, crr) => {
          if (crr.value) {
            arr[crr.value] = crr.name;
          }
          return arr;
        }, {});
        const result = this.toFormObject(apiSave, formData, feildMaps);
        return result;
      },
      toFormObject(arr, formData, feildMaps) {
        const result = {};
        const objectData = arr.filter((item) => item.type == "object");
        const arrayData = arr.filter((item) => item.type == "array");
        const basicData = arr.filter((item) => {
          return !item.parent && item.type == "basic";
        });

        objectData.forEach((item) => {
          const child = arr.filter((t) => t.parent == item.name);
          result[item.name] = child.reduce((acc, crr) => {
            acc[crr.name] = this.findFormDatatoValue(crr.value, formData, feildMaps);
            return acc;
          }, {});
        });

        arrayData.forEach((item) => {
          result[item.name] = this.findFormDatatoValue(item.value, formData, feildMaps);
        });

        basicData.forEach((item) => {
          result[item.name] = this.findFormDatatoValue(item.value, formData, feildMaps);
        });

        return result;
      },
      findFormDatatoValue(id, formData, feildMaps) {
        let result;
        if (Array.isArray(formData[id])) {
          result = formData[id].map((item) => {
            if (Object.prototype.toString.call(item) == "[object Object]") {
              return Object.keys(item).reduce((acc, crr) => {
                acc[feildMaps[crr]] = item[crr];
                return acc;
              }, {});
            }
            return item;
          });
        } else {
          result = formData[id];
        }
        return result;
      },
    },
  };
}
